Current File : //usr/lib/python3/dist-packages/twisted/web/__pycache__/_http2.cpython-312.pyc
�

Ϫ�f���h�UdZddlZddlmZddlmZddlmZddlZ	ddl
Z	ddlZ	ddlZ	ddl
Z	ddlZddlmZddlmZddlmZdd	lmZmZmZmZmZdd
lmZddlmZddlm Z dd
l!m"Z"ddl#m$Z$gZ%ee&e'd<e(�Z)eee�Gd�dee ��Z*eeee�Gd�d��Z+d�Z,y)a�
HTTP2 Implementation

This is the basic server-side protocol implementation used by the Twisted
Web server for HTTP2.  This functionality is intended to be combined with the
HTTP/1.1 and HTTP/1.0 functionality in twisted.web.http to provide complete
protocol support for HTTP-type protocols.

This API is currently considered private because it's in early draft form. When
it has stabilised, it'll be made public.
�N)�deque)�List)�implementer)�_PullToPush)�Deferred)�ConnectionLost)�	IConsumer�	IProtocol�
IPushProducer�
ISSLTransport�
ITransport)�Protocol)�Logger)�TimeoutMixin)�Failure)�ExcessiveBufferingError�__all__c���eZdZdZdZdZdZe�ZdZ	d#d�Z
d�Zd�Zd�Z
d�Zd$d	�Zd
�Zd�Zd�Zd
�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Z d�Z!d�Z"d�Z#d�Z$d�Z%d �Z&d!�Z'd"�Z(y)%�H2Connectiona

    A class representing a single HTTP/2 connection.

    This implementation of L{IProtocol} works hand in hand with L{H2Stream}.
    This is because we have the requirement to register multiple producers for
    a single HTTP/2 connection, one for each stream. The standard Twisted
    interfaces don't really allow for this, so instead there's a custom
    interface between the two objects that allows them to work hand-in-hand here.

    @ivar conn: The HTTP/2 connection state machine.
    @type conn: L{h2.connection.H2Connection}

    @ivar streams: A mapping of stream IDs to L{H2Stream} objects, used to call
        specific methods on streams when events occur.
    @type streams: L{dict}, mapping L{int} stream IDs to L{H2Stream} objects.

    @ivar priority: A HTTP/2 priority tree used to ensure that responses are
        prioritised appropriately.
    @type priority: L{priority.PriorityTree}

    @ivar _consumerBlocked: A flag tracking whether or not the L{IConsumer}
        that is consuming this data has asked us to stop producing.
    @type _consumerBlocked: L{bool}

    @ivar _sendingDeferred: A L{Deferred} used to restart the data-sending loop
        when more response data has been produced. Will not be present if there
        is outstanding data still to send.
    @type _consumerBlocked: A L{twisted.internet.defer.Deferred}, or L{None}

    @ivar _outboundStreamQueues: A map of stream IDs to queues, used to store
        data blocks that are yet to be sent on the connection. These are used
        both to handle producers that do not respect L{IConsumer} but also to
        allow priority to multiplex data appropriately.
    @type _outboundStreamQueues: A L{dict} mapping L{int} stream IDs to
        L{collections.deque} queues, which contain either L{bytes} objects or
        C{_END_STREAM_SENTINEL}.

    @ivar _sender: A handle to the data-sending loop, allowing it to be
        terminated if needed.
    @type _sender: L{twisted.internet.task.LoopingCall}

    @ivar abortTimeout: The number of seconds to wait after we attempt to shut
        the transport down cleanly to give up and forcibly terminate it. This
        is only used when we time a connection out, to prevent errors causing
        the FD to get leaked. If this is L{None}, we will wait forever.
    @type abortTimeout: L{int}

    @ivar _abortingCall: The L{twisted.internet.base.DelayedCall} that will be
        used to forcibly close the transport if it doesn't close cleanly.
    @type _abortingCall: L{twisted.internet.base.DelayedCall}
    N�c��tjjdd��}tjj	|��|_i|_tj�|_d|_	d|_
i|_i|_d|_
d|_t�|_d|_|�ddlm}||_|j(j+d|j,�y)NF)�client_side�header_encoding)�configTiDr)�reactor)�h2r�H2Configuration�
connectionr�conn�streams�priority�PriorityTree�_consumerBlocked�_sendingDeferred�_outboundStreamQueues�_streamCleanupCallbacks�_stillProducing�_maxBufferedControlFrameBytesr�_bufferedControlFrames�_bufferedControlFrameBytes�twisted.internetr�_reactor�	callLater�_sendPrioritisedData)�selfrrs   �4/usr/lib/python3/dist-packages/twisted/web/_http2.py�__init__zH2Connection.__init__ss������*�*�u�d�*�S���M�M�.�.�f�.�=��	���� �-�-�/��
� $��� $���%'��"�')��$�#���.7��*�&+�g��#�*+��'��?�0���
�	
�
�
����4�#<�#<�=�c���|j|j�|jj�|jj|jj
��y)z�
        Called by the reactor when a connection is received. May also be called
        by the L{twisted.web.http._GenericHTTPChannelProtocol} during upgrade
        to HTTP/2.
        N)�
setTimeout�timeOutr�initiate_connection�	transport�write�data_to_send�r/s r0�connectionMadezH2Connection.connectionMade�sC��	
������%��	�	�%�%�'������T�Y�Y�3�3�5�6r2c��	|jj|�}|j�|D�]�}t|tjj�r|j|��:t|tjj�r|j!|��pt|tjj"�r|j%|���t|tjj&�r|j)|���t|tjj*�r|j-|���t|tjj.�r|j1|���Jt|tjj2�s��p|jj�|jtt5d��d�����|j�y#tjj$rJ|j�}|r5|jj�|jt�d��YywxYw)z�
        Called whenever a chunk of data is received from the transport.

        @param data: The data received from the transport.
        @type data: L{bytes}
        F)�_cancelTimeoutsNzRemote peer sent GOAWAY)r�receive_datar�
exceptions�
ProtocolError�_tryToWriteControlDatar7�loseConnection�connectionLostr�resetTimeout�
isinstance�events�RequestReceived�_requestReceived�DataReceived�_requestDataReceived�StreamEnded�
_requestEnded�StreamReset�_requestAborted�
WindowUpdated�_handleWindowUpdate�PriorityUpdated�_handlePriorityUpdate�ConnectionTerminatedr)r/�datarF�stillActive�events     r0�dataReceivedzH2Connection.dataReceived�s���	��Y�Y�+�+�D�1�F�	
�����	�E��%����!:�!:�;��%�%�e�,��E�2�9�9�#9�#9�:��)�)�%�0��E�2�9�9�#8�#8�9��"�"�5�)��E�2�9�9�#8�#8�9��$�$�U�+��E�2�9�9�#:�#:�;��(�(��/��E�2�9�9�#<�#<�=��*�*�5�1��E�2�9�9�#A�#A�B����-�-�/��#�#��N�+D�E�F�$)�$��	�(	
�#�#�%��?�}�}�*�*�	��5�5�7�K�����-�-�/��#�#�G�I�u�#�E��	�s�G2�2A$I�Ic��|jjd|jj���|jj
dkDs|jjdkDr%tjjj}n$tjjj}|jj|��|jj|jj��|j�+|j!|j|j"�|_|jj'�y)a-
        Called when the connection has been inactive for
        L{self.timeOut<twisted.protocols.policies.TimeoutMixin.timeOut>}
        seconds. Cleanly tears the connection down, attempting to notify the
        peer if needed.

        We override this method to add two extra bits of functionality:

         - We want to log the timeout.
         - We want to send a GOAWAY frame indicating that the connection is
           being terminated, and whether it was clean or not. We have to do this
           before the connection is torn down.
        zTiming out client {client}��clientr)�
error_codeN)�_log�infor7�getPeerr�open_outbound_streams�open_inbound_streamsr�errors�
ErrorCodes�PROTOCOL_ERROR�NO_ERROR�close_connectionr8r9�abortTimeoutr-�forceAbortClient�
_abortingCallrB)r/r[s  r0�timeoutConnectionzH2Connection.timeoutConnection�s���	
�	�	���3�D�N�N�<R�<R�<T��U�
�9�9�*�*�Q�.�$�)�)�2P�2P�ST�2T����-�-�<�<�J����-�-�6�6�J��	�	�"�"�j�"�9������T�Y�Y�3�3�5�6����(�"&����!�!�4�#8�#8�"�D��
	
���%�%�'r2c��|jjd|jj���d|_|jj�y)a
        Called if C{abortTimeout} seconds have passed since the timeout fired,
        and the connection still hasn't gone away. This can really only happen
        on extremely bad connections or when clients are maliciously attempting
        to keep connections open.
        z$Forcibly timing out client: {client}rYN)r\r]r7r^rh�abortConnectionr:s r0rgzH2Connection.forceAbortClient�sE��	
�	�	���2�4�>�>�;Q�;Q�;S�	�	
�
"������&�&�(r2c�l�d|_|r|jd�|jj�D]}|j	|��t|jj
��D]}|j|��|r/|j�"|jj�d|_yyy)a�
        Called when the transport connection is lost.

        Informs all outstanding response handlers that the connection
        has been lost, and cleans up all internal state.

        @param reason: See L{IProtocol.connectionLost}

        @param _cancelTimeouts: Propagate the C{reason} to this
            connection's streams but don't cancel any timers, so that
            peers who never read the data we've written are eventually
            timed out.
        FN)
r'r4r �valuesrC�list�keys�_requestDonerh�cancel)r/�reasonr=�stream�streamIDs     r0rCzH2Connection.connectionLost�s��� %�����O�O�D�!��l�l�)�)�+�	*�F��!�!�&�)�	*��T�\�\�.�.�0�1�	(�H����h�'�	(��t�1�1�=����%�%�'�!%�D�� >�?r2c�J�|jttd���y)z�
        Stop producing data.

        This tells the L{H2Connection} that its consumer has died, so it must
        stop producing data for good.
        zProducing stoppedN)rCrrr:s r0�
stopProducingzH2Connection.stopProducingAs��	
���G�N�3F�$G�H�Ir2c�l�t�|_|jj|j�y)z�
        Pause producing data.

        Tells the L{H2Connection} that it has produced too much data to process
        for the time being, and to stop until resumeProducing() is called.
        N)rr#�addCallback�_flushBufferedControlDatar:s r0�pauseProducingzH2Connection.pauseProducingJs(��!)�
������)�)�$�*H�*H�Ir2c�f�|j�%|j}d|_|jd�yy)z�
        Resume producing data.

        This tells the L{H2Connection} to re-add itself to the main loop and
        produce more data for the consumer.
        N)r#�callback)r/�ds  r0�resumeProducingzH2Connection.resumeProducingUs4��� � �,��%�%�A�$(�D�!�
�J�J�t��-r2c�"�|jsyd}|�	t|j�}|��|j�&|jj
|j�y|j�|jj|�}|j|j�}t|jj|�}|t ur`|jj#|�|j$j'|jj)��|j+|�n�t-|�|kDr(||d}|d|}|j|j/|�|rO|jj1||�|j$j'|jj)��|j|s|jj3|�|j5|�dkr|j6|j9�|j:j=d|j�y#tj$rE|j�J�t�|_|jj
|j�YywxYw)a�
        The data sending loop. This function repeatedly calls itself, either
        from L{Deferred}s or from
        L{reactor.callLater<twisted.internet.interfaces.IReactorTime.callLater>}

        This function sends data on streams according to the rules of HTTP/2
        priority. It ensures that the data from each stream is interleved
        according to the priority signalled by the client, making sure that the
        connection is used with maximal efficiency.

        This function will execute if data is available: if all data is
        exhausted, the function will place a deferred onto the L{H2Connection}
        object and wait until it is called to resume executing.
        Nr)r'�nextr!�
DeadlockErrorr$rrxr.r#rDr�local_flow_control_windowr%�popleft�min�max_outbound_frame_size�_END_STREAM_SENTINEL�
end_streamr7r8r9rp�len�
appendleft�	send_data�block�remainingOutboundWindowr �flowControlBlockedr,r-)r/�argsrs�remainingWindow�	frameData�maxFrameSize�
excessDatas       r0r.z!H2Connection._sendPrioritisedDataas*�� �#�#�����n�
��d�m�m�,���n�� � �,��!�!�-�-�d�.G�.G�H�������)�)�=�=�f�E���.�.�v�6�>�>�@�	��4�9�9�<�<�o�N���,�,�
�I�I� � ��(��N�N� � ����!7�!7�!9�:�
���f�%��9�~��,�&�|�}�5�
�%�m�|�4�	��*�*�6�2�=�=�j�I���	�	�#�#�F�I�6����$�$�T�Y�Y�%;�%;�%=�>��-�-�f�5��
�
�#�#�F�+��+�+�F�3�q�8����V�$�7�7�9��
�
����4�#<�#<�=��i�)�)�
��,�,�4�4�4�(0�
��%��%�%�1�1�$�2K�2K�L��

�s�H6�6AJ�
Jc��t|j||j|j|j|j
�}||j|j<t�|j|j<t�|j|j<	|jj|j�|jj|j�y#tj$rYywxYw)z�
        Internal handler for when a request has been received.

        @param event: The Hyper-h2 event that encodes information about the
            received request.
        @type event: L{h2.events.RequestReceived}
        N)�H2Stream�	stream_id�headers�requestFactory�site�factoryr rr&rr%r!�
insert_streamr��DuplicateStreamError�r/rVrss   r0rHzH2Connection._requestReceived�s�����O�O���M�M�����I�I��L�L�

��)/����U�_�_�%�8@�
��$�$�U�_�_�5�6;�g��"�"�5�?�?�3�	1��M�M�'�'����8�
�M�M������0��
�,�,�	�
�		�s�%C*�*D�?Dc��|j|j}|j|j|j�y)z�
        Internal handler for when a chunk of data is received for a given
        request.

        @param event: The Hyper-h2 event that encodes information about the
            received data.
        @type event: L{h2.events.DataReceived}
        N)r r��receiveDataChunkrT�flow_controlled_lengthr�s   r0rJz!H2Connection._requestDataReceived�s0�����e�o�o�.������
�
�E�,H�,H�Ir2c�V�|j|j}|j�y)a
        Internal handler for when a request is complete, and we expect no
        further data for that request.

        @param event: The Hyper-h2 event that encodes information about the
            completed stream.
        @type event: L{h2.events.StreamEnded}
        N)r r��requestCompleter�s   r0rLzH2Connection._requestEnded�s"�����e�o�o�.����� r2c���|j|j}|jtt	d|j
z���|j
|j�y)z�
        Internal handler for when a request is aborted by a remote peer.

        @param event: The Hyper-h2 event that encodes information about the
            reset stream.
        @type event: L{h2.events.StreamReset}
        zStream reset with code %sN)r r�rCrrr[rpr�s   r0rNzH2Connection._requestAborted�sQ�����e�o�o�.������N�#>��AQ�AQ�#Q�R�S�	
�	
���%�/�/�*r2c��	|jj|j|jxsd|j|j
��y#tj$rs|jj|j|jxsd|j|j
��|jj|j�YywxYw)z�
        Internal handler for when a stream priority is updated.

        @param event: The Hyper-h2 event that encodes information about the
            stream reprioritization.
        @type event: L{h2.events.PriorityUpdated}
        N)r��
depends_on�weight�	exclusive)	r!�reprioritizer�r�r�r��MissingStreamErrorr�r�)r/rVs  r0rRz"H2Connection._handlePriorityUpdate�s���	1��M�M�&�&��/�/� �+�+�3�t��|�|��/�/�	
'�
���*�*�
	1�
�M�M�'�'��/�/� �+�+�3�t��|�|��/�/�	
(�
�
�M�M������0�
	1�s�AA�BC�Cc���|jdd|f�	|jj||�|j�y#tj
j$rYywxYw)a{
        Called by L{twisted.web.http.Request} objects to write a complete set
        of HTTP headers to a stream.

        @param version: The HTTP version in use. Unused in HTTP/2.
        @type version: L{bytes}

        @param code: The HTTP status code to write.
        @type code: L{bytes}

        @param reason: The HTTP reason phrase to write. Unused in HTTP/2.
        @type reason: L{bytes}

        @param headers: The headers to write to the stream.
        @type headers: L{twisted.web.http_headers.Headers}

        @param streamID: The ID of the stream to write the headers to.
        @type streamID: L{int}
        r�:statusN)�insertr�send_headersrArr?�StreamClosedError)r/�version�coderrr�rts      r0�writeHeaderszH2Connection.writeHeaderss^��(	���q�:�t�,�-�	*��I�I�"�"�8�W�5�
�'�'�)��
�}�}�.�.�	�
�		�s�A�A#�"A#c�v�|j|j|�|jj|�dkDrK|jj|�|j�$|j}d|_|j|�|j|�dkr|j|j�yy)aB
        May be called by L{H2Stream} objects to write response data to a given
        stream. Writes a single data frame.

        @param streamID: The ID of the stream to write the data to.
        @type streamID: L{int}

        @param data: The data chunk to write to the stream.
        @type data: L{bytes}
        rN)r%�appendrr�r!�unblockr$r|r�r r�)r/rtrTr}s    r0�writeDataToStreamzH2Connection.writeDataToStream0s���	
�"�"�8�,�3�3�D�9�
�9�9�.�.�x�8�1�<��M�M�!�!�(�+��$�$�0��)�)��(,��%��
�
�8�$��'�'��1�Q�6��L�L��"�5�5�7�7r2c���|j|jt�|jj	|�|j
�%|j
}d|_|j
|�yy)z�
        Called by L{H2Stream} objects to signal completion of a response.

        @param streamID: The ID of the stream to write the data to.
        @type streamID: L{int}
        N)r%r�r�r!r�r$r|)r/rtr}s   r0�
endRequestzH2Connection.endRequestJs`��	
�"�"�8�,�3�3�4H�I��
�
���h�'�� � �,��%�%�A�$(�D�!�
�J�J�x� �-r2c��|jj|�|j�}|r|j|�yy)a
        Called by L{H2Stream} objects to request early termination of a stream.
        This emits a RstStream frame and then removes all stream state.

        @param streamID: The ID of the stream to write the data to.
        @type streamID: L{int}
        N)r�reset_streamrArp)r/rtrUs   r0�abortRequestzH2Connection.abortRequestXs:��	
�	�	���x�(��1�1�3������h�'�r2c���|j|=|jj|�|j|=|jj|�}|j
|�y)a
        Called internally by the data sending loop to clean up state that was
        being used for the stream. Called when the stream is complete.

        @param streamID: The ID of the stream to clean up state for.
        @type streamID: L{int}
        N)r%r!�
remove_streamr r&�popr|)r/rt�cleanupCallbacks   r0rpzH2Connection._requestDoneesT��
�&�&�x�0��
�
�#�#�H�-��L�L��"��6�6�:�:�8�D��� � ��*r2c��|jj|�}|j|}td�|D��}||z
S)a�
        Called to determine how much room is left in the send window for a
        given stream. Allows us to handle blocking and unblocking producers.

        @param streamID: The ID of the stream whose flow control window we'll
            check.
        @type streamID: L{int}

        @return: The amount of room remaining in the send window for the given
            stream, including the data queued to be sent.
        @rtype: L{int}
        c3�DK�|]}|tus�t|����y�w�N)r�r�)�.0�chunks  r0�	<genexpr>z7H2Connection.remainingOutboundWindow.<locals>.<genexpr>�s!����
� ��>R�1R�C��J�
�s�
 � )rr�r%�sum)r/rt�
windowSize�	sendQueue�alreadyConsumeds     r0r�z$H2Connection.remainingOutboundWindowssL���Y�Y�8�8��B�
��.�.�x�8�	��
�$-�
�
���O�+�+r2c���|j}|rf|j|�sy|jj|�r|jj|�|j|j�y|jj�D]]}|j�|jj|j�s�9|jj|j��_y)a�
        Manage flow control windows.

        Streams that are blocked on flow control will register themselves with
        the connection. This will fire deferreds that wake those streams up and
        allow them to continue processing.

        @param event: The Hyper-h2 event that encodes information about the
            flow control window change.
        @type event: L{h2.events.WindowUpdated}
        N)
r��_streamIsActiver%�getr!r�r �
windowUpdatedrmrt)r/rVrtrss    r0rPz H2Connection._handleWindowUpdate�s����?�?����'�'��1��
�)�)�-�-�h�7��
�
�%�%�h�/��L�L��"�0�0�2��,�,�-�-�/�
;���$�$�&��-�-�1�1�&�/�/�B��M�M�)�)�&�/�/�:�
;r2c�6�|jj�S)ah
        Get the remote address of this connection.

        Treat this method with caution.  It is the unfortunate result of the
        CGI and Jabber standards, but should not be considered reliable for
        the usual host of reasons; port forwarding, proxying, firewalls, IP
        masquerading, etc.

        @return: An L{IAddress} provider.
        )r7r^r:s r0r^zH2Connection.getPeer�s���~�~�%�%�'�'r2c�6�|jj�S)z�
        Similar to getPeer, but returns an address describing this side of the
        connection.

        @return: An L{IAddress} provider.
        )r7�getHostr:s r0r�zH2Connection.getHost�s���~�~�%�%�'�'r2c�\�|jj||�|j�y)a+
        Open the stream window by a given increment.

        @param streamID: The ID of the stream whose window needs to be opened.
        @type streamID: L{int}

        @param increment: The amount by which the stream window must be
        incremented.
        @type increment: L{int}
        N)r�acknowledge_received_datarA)r/rt�	increments   r0�openStreamWindowzH2Connection.openStreamWindow�s$��	
�	�	�+�+�I�x�@��#�#�%r2c�2�t|jd�duS)��
        Returns L{True} if this channel is using a secure transport.

        @returns: L{True} if this channel is secure.
        @rtype: L{bool}
        N)rr7r:s r0�	_isSecurezH2Connection._isSecure�s���T�^�^�T�2�$�>�>r2c�d�dg}|jj||��|j�y)z�
        Sends a 100 Continue response, used to signal to clients that further
        processing will be performed.

        @param streamID: The ID of the stream that needs the 100 Continue
        response
        @type streamID: L{int}
        )r�s100)r�r�N)rr�rA)r/rtr�s   r0�_send100ContinuezH2Connection._send100Continue�s/��(�(���	�	���w�(��C��#�#�%r2c���dg}|jj||d��|j�}|rD|j|}|j	tt
d���|j|�yy)af
        This is a quick and dirty way of responding to bad requests.

        As described by HTTP standard we should be patient and accept the
        whole request from the client before sending a polite bad request
        response, even in the case when clients send tons of data.

        Unlike in the HTTP/1.1 case, this does not actually disconnect the
        underlying transport: there's no need. This instead just sends a 400
        response and terminates the stream.

        @param streamID: The ID of the stream that needs the 100 Continue
        response
        @type streamID: L{int}
        )r�s400T)r�r�r�zInvalid requestN)rr�rAr rCrrrp)r/rtr�rUrss     r0�!_respondToBadRequestAndDisconnectz.H2Connection._respondToBadRequestAndDisconnect�sp�� (�(���	�	���w�(�t��T��1�1�3����\�\�(�+�F��!�!�'�.�9J�*K�"L�M����h�'�r2c��||jvS)a?
        Checks whether Twisted has still got state for a given stream and so
        can process events for that stream.

        @param streamID: The ID of the stream that needs processing.
        @type streamID: L{int}

        @return: Whether the stream still has state allocated.
        @rtype: L{bool}
        )r )r/rts  r0r�zH2Connection._streamIsActives���4�<�<�'�'r2c�^�|jj�}|sy|j�(|js|jj|�y|jj
|�|xjt|�z
c_|j|jk\r�|j}|jjd|j||jj���|jj�|jtt!���yy)aE
        Checks whether the connection is blocked on flow control and,
        if it isn't, writes any buffered control data.

        @return: L{True} if the connection is still active and
            L{False} if it was aborted because too many bytes have
            been written but not consumed by the other end.
        Tz�Maximum number of control frame bytes buffered: {bufferedControlFrameBytes} > = {maxBufferedControlFrameBytes}. Aborting connection to client: {client} )�bufferedControlFrameBytes�maxBufferedControlFrameBytesrZF)rr9r#r)r7r8r�r*r�r(r\�errorr^rkrCrr)r/�
bufferedBytes�maxBuffCtrlFrameBytess   r0rAz#H2Connection._tryToWriteControlDatas����	�	�.�.�0�
���� � �(��1L�1L�
�N�N� � ��/��
�'�'�.�.�}�=��+�+�s�=�/A�A�+��.�.�$�2T�2T�T�(,�(J�(J�%��	�	���?�/3�.M�.M�1F��>�>�1�1�3� �����.�.�0��#�#�G�,C�,E�$F�G��r2c��|j�{|jrn|jj�}|xjt	|�zc_|j
j
|�|j�|jr�lyyyy)z�
        Called when the connection is marked writable again after being marked unwritable.
        Attempts to flush buffered control data if there is any.
        N)r#r)r�r*r�r7r8)r/r��	nextWrites   r0ryz&H2Connection._flushBufferedControlData;sr���#�#�+��0K�0K��3�3�;�;�=�I��+�+�s�9�~�=�+��N�N� � ��+��#�#�+��0K�0K�+�0K�+r2r�)T))�__name__�
__module__�__qualname__�__doc__r�r�rfrr\rhr1r;rWrirgrCrvrzr~r.rHrJrLrNrRr�r�r�r�rpr�rPr^r�r�r�r�r�r�rAry�r2r0rr6s���2�h�G��D��L��8�D��M�>�47�(&�T%(�N
)�&�TJ�	J�
�L>�^1�>
J�
!�+�1�6*�@8�4!�(�+�,�.";�H(�(�&�?�&�(�0(�+�Z
,r2rc��eZdZdZdZd�Zd�Zd�Zd�Zd�Z	d�Z
d	�Zd
�Zd�Z
d�Zd
�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zd�Zy)r�a
    A class representing a single HTTP/2 stream.

    This class works hand-in-hand with L{H2Connection}. It acts to provide an
    implementation of L{ITransport}, L{IConsumer}, and L{IProducer} that work
    for a single HTTP/2 connection, while tightly cleaving to the interface
    provided by those interfaces. It does this by having a tight coupling to
    L{H2Connection}, which allows associating many of the functions of
    L{ITransport}, L{IConsumer}, and L{IProducer} to objects on a
    stream-specific level.

    @ivar streamID: The numerical stream ID that this object corresponds to.
    @type streamID: L{int}

    @ivar producing: Whether this stream is currently allowed to produce data
        to its consumer.
    @type producing: L{bool}

    @ivar command: The HTTP verb used on the request.
    @type command: L{unicode}

    @ivar path: The HTTP path used on the request.
    @type path: L{unicode}

    @ivar producer: The object producing the response, if any.
    @type producer: L{IProducer}

    @ivar site: The L{twisted.web.server.Site} object this stream belongs to,
        if any.
    @type site: L{twisted.web.server.Site}

    @ivar factory: The L{twisted.web.http.HTTPFactory} object that constructed
        this stream's parent connection.
    @type factory: L{twisted.web.http.HTTPFactory}

    @ivar _producerProducing: Whether the producer stored in producer is
        currently producing data.
    @type _producerProducing: L{bool}

    @ivar _inboundDataBuffer: Any data that has been received from the network
        but has not yet been received by the consumer.
    @type _inboundDataBuffer: A L{collections.deque} containing L{bytes}

    @ivar _conn: A reference to the connection this stream belongs to.
    @type _conn: L{H2Connection}

    @ivar _request: A request object that this stream corresponds to.
    @type _request: L{twisted.web.iweb.IRequest}

    @ivar _buffer: A buffer containing data produced by the producer that could
        not be sent on the network at this time.
    @type _buffer: L{io.BytesIO}
    Nc� �||_||_||_d|_d|_d|_d|_d|_d|_t�|_
||_||d��|_tj�|_|j!|�y)a�
        Initialize this HTTP/2 stream.

        @param streamID: The numerical stream ID that this object corresponds
            to.
        @type streamID: L{int}

        @param connection: The HTTP/2 connection this stream belongs to.
        @type connection: L{H2Connection}

        @param headers: The HTTP/2 request headers.
        @type headers: A L{list} of L{tuple}s of header name and header value,
            both as L{bytes}.

        @param requestFactory: A function that builds appropriate request
            request objects.
        @type requestFactory: A callable that returns a
            L{twisted.web.iweb.IRequest}.

        @param site: The L{twisted.web.server.Site} object this stream belongs
            to, if any.
        @type site: L{twisted.web.server.Site}

        @param factory: The L{twisted.web.http.HTTPFactory} object that
            constructed this stream's parent connection.
        @type factory: L{twisted.web.http.HTTPFactory}
        TNF)�queued)rtr�r��	producing�command�path�producer�_producerProducing�_hasStreamingProducerr�_inboundDataBuffer�_conn�_request�io�BytesIO�_buffer�_convertHeaders)r/rtrr�r�r�r�s       r0r1zH2Stream.__init__�s��:!��
���	������������	���
�"'���%)��"�"'�'�����
�&�t�E�:��
��z�z�|������W�%r2c�h�d}|D]{}|djd�st|j|�xs|}�2|ddk(r|d|_�E|ddk(r|d|_�X|ddk(s�at|jd|df��}|sE|jd	vr|jjd�n|jjd
�|jj
�|jjjd�}|r(|dj�dk(r|j�y
y
y
)
aZ
        This method converts the HTTP/2 header set into something that looks
        like HTTP/1.1. In particular, it strips the 'special' headers and adds
        a Host: header.

        @param headers: The HTTP/2 header set.
        @type headers: A L{list} of L{tuple}s of header name and header value,
            both as L{bytes}.
        Fr�:s:method�s:paths
:authorityshost)sGETsHEADNsexpects100-continue)�
startswith�_addHeaderToRequestr�r�r��	gotLength�parseCookies�requestHeaders�
getRawHeaders�lowerr�)r/r�r��header�expectContinues     r0r�zH2Stream._convertHeaders�s���	��		I�F��!�9�'�'��-�/��
�
�v�F�S�)�	����j�(�%�a�y������h�&�"�1�I��	����m�+�#�D�M�M�G�V�A�Y�3G�H�		I���|�|�0�0��
�
�'�'��*��
�
�'�'��-��
�
�"�"�$����5�5�C�C�I�N���n�Q�/�5�5�7�?�J��!�!�#�K�>r2c���|js|jj||f�y|jj	|�|j
j
|j|�y)av
        Called when the connection has received a chunk of data from the
        underlying transport. If the stream has been registered with a
        consumer, and is currently able to push data, immediately passes it
        through. Otherwise, buffers the chunk until we can start producing.

        @param data: The chunk of data that was received.
        @type data: L{bytes}

        @param flowControlledLength: The total flow controlled length of this
            chunk, which is used when we want to re-open the window. May be
            different to C{len(data)}.
        @type flowControlledLength: L{int}
        N)r�r�r�r��handleContentChunkr�r�rt)r/rT�flowControlledLengths   r0r�zH2Stream.receiveDataChunk�sP���~�~��#�#�*�*�D�2F�+G�H��M�M�,�,�T�2��J�J�'�'��
�
�7K�Lr2c���|jr2|jj|j|jd�y|j
j
tdf�y)z�
        Called by the L{H2Connection} when the all data for a request has been
        received. Currently, with the legacy L{twisted.web.http.Request}
        object, just calls requestReceived unless the producer wants us to be
        quiet.
        sHTTP/2N)r�r��requestReceivedr�r�r�r�r�r:s r0r�zH2Stream.requestComplete�sC���>�>��M�M�)�)�$�,�,��	�	�9�M��#�#�*�*�,@�$�+G�Hr2c�:�|jj|�y)z�
        Called by the L{H2Connection} when a connection is lost or a stream is
        reset.

        @param reason: The reason the connection was lost.
        @type reason: L{str}
        N)r�rC)r/rrs  r0rCzH2Stream.connectionLost�s��	
�
�
�$�$�V�,r2c���|jsy|jry|jj|j�}|dkDsyd|_|jj�y)zo
        Called by the L{H2Connection} when this stream's flow control window
        has been opened.
        NrT)r�r�r�r�rtr~)r/r�s  r0r�zH2Stream.windowUpdateds[���}�}���"�"��
�*�*�<�<�T�]�]�K����"��#'����
�
�%�%�'r2c�z�|jsy|jr"|jj�d|_yy)zr
        Called by the L{H2Connection} when this stream's flow control window
        has been exhausted.
        NF)r�r�rzr:s r0r�zH2Stream.flowControlBlockeds4��
�}�}���"�"��M�M�(�(�*�&+�D�#�#r2c�V�|jj|||||j�y)a�
        Called by the consumer to write headers to the stream.

        @param version: The HTTP version.
        @type version: L{bytes}

        @param code: The status code.
        @type code: L{int}

        @param reason: The reason phrase. Ignored in HTTP/2.
        @type reason: L{bytes}

        @param headers: The HTTP response headers.
        @type headers: Any iterable of two-tuples of L{bytes}, representing header
            names and header values.
        N)r�r�rt)r/r�r�rrr�s     r0r�zH2Stream.writeHeaders&s"��"	
�
�
�����v�w��
�
�Nr2c�N�|jj|j�y)z�
        Called by a consumer to clean up whatever permanent state is in use.

        @param request: The request calling the method.
        @type request: L{twisted.web.iweb.IRequest}
        N�r�r�rt)r/�requests  r0�requestDonezH2Stream.requestDone9s��	
�
�
���d�m�m�,r2c�N�|jj|j�y)z}
        Sends a 100 Continue response, used to signal to clients that further
        processing will be performed.
        N)r�r�rtr:s r0r�zH2Stream._send100ContinueBs��
	
�
�
�#�#�D�M�M�2r2c�N�|jj|j�y)a�
        This is a quick and dirty way of responding to bad requests.

        As described by HTTP standard we should be patient and accept the
        whole request from the client before sending a polite bad request
        response, even in the case when clients send tons of data.

        Unlike in the HTTP/1.1 case, this does not actually disconnect the
        underlying transport: there's no need. This instead just sends a 400
        response and terminates the stream.
        N)r�r�rtr:s r0r�z*H2Stream._respondToBadRequestAndDisconnectIs��	
�
�
�4�4�T�]�]�Cr2c�P�|jj|j|�y)z�
        Write a single chunk of data into a data frame.

        @param data: The data chunk to send.
        @type data: L{bytes}
        N)r�r�rt)r/rTs  r0r8zH2Stream.writeXs��	
�
�
�$�$�T�]�]�D�9�r2c�4�|D]}|j|��y)z�
        Write a sequence of chunks of data into data frames.

        @param iovec: A sequence of chunks to send.
        @type iovec: An iterable of L{bytes} chunks.
        N)r8)r/�iovecr�s   r0�
writeSequencezH2Stream.writeSequencebs���	�E��J�J�u��	r2c�N�|jj|j�y)zF
        Close the connection after writing all pending data.
        Nrr:s r0rBzH2Stream.loseConnectionls��	
�
�
���d�m�m�,r2c�N�|jj|j�y)zO
        Forcefully abort the connection by sending a RstStream frame.
        N)r�r�rtr:s r0rkzH2Stream.abortConnectionrs��	
�
�
����
�
�.r2c�6�|jj�S)z1
        Get information about the peer.
        )r�r^r:s r0r^zH2Stream.getPeerx����z�z�!�!�#�#r2c�6�|jj�S)zJ
        Similar to getPeer, but for this side of the connection.
        )r�r�r:s r0r�zH2Stream.getHost~rr2c�6�|jj�S)r�)r�r�r:s r0�isSecurezH2Stream.isSecure�s���z�z�#�#�%�%r2c���|jrtd|�d|j�d���|s$d|_t||�}|j	�nd|_||_d|_y)a�
        Register to receive data from a producer.

        This sets self to be a consumer for a producer.  When this object runs
        out of data (as when a send(2) call on a socket succeeds in moving the
        last data from a userspace buffer into a kernelspace buffer), it will
        ask the producer to resumeProducing().

        For L{IPullProducer} providers, C{resumeProducing} will be called once
        each time data is required.

        For L{IPushProducer} providers, C{pauseProducing} will be called
        whenever the write buffer fills up and C{resumeProducing} will only be
        called when it empties.

        @param producer: The producer to register.
        @type producer: L{IProducer} provider

        @param streaming: L{True} if C{producer} provides L{IPushProducer},
        L{False} if C{producer} provides L{IPullProducer}.
        @type streaming: L{bool}

        @raise RuntimeError: If a producer is already registered.

        @return: L{None}
        zregistering producer z before previous one (z) was unregisteredFTN)r��
ValueError�hasStreamingProducerr�startStreamingr�)r/r��	streamings   r0�registerProducerzH2Stream.registerProducer�sb��6�=�=��"*�D�M�M�;��
�
�(-�D�%�"�8�T�2�H��#�#�%�(,�D�%� ��
�"&��r2c��|j�&|js|jj�d|_d|_d|_y)z7
        @see: L{IConsumer.unregisterProducer}
        NF)r�r �
stopStreamingr�r:s r0�unregisterProducerzH2Stream.unregisterProducer�s=��
�=�=�$�T�-F�-F��M�M�'�'�)�"'�����
�$(��!r2c�2�d|_|j�y)z2
        @see: L{IProducer.stopProducing}
        FN)r�rkr:s r0rvzH2Stream.stopProducing�s��������r2c��d|_y)z7
        @see: L{IPushProducer.pauseProducing}
        FN)r�r:s r0rzzH2Stream.pauseProducing�s����r2c�p�d|_d}|jr{|jro|jj�\}}|tur|j	�n ||z
}|j
j
|�|jr
|jr�o|jj|j|�y)z8
        @see: L{IPushProducer.resumeProducing}
        TrN)
r�r�r�r�r�r�rr�r�rt)r/�consumedLengthr�rs    r0r~zH2Stream.resumeProducing�s���������n�n��!8�!8�+/�*A�*A�*I�*I�*K�'�E�'��,�,��$�$�&��"6�6���
�
�0�0��7��n�n��!8�!8�	
�
�
�#�#�D�M�M�>�Br2)r�r�r�r�r7r1r�r�r�rCr�r�r�rr�r�r8rrBrkr^r�rr#r&rvrzr~r�r2r0r�r�Hs���4�p�I�+&�Z $�FM�,
I�-�(�2
,�O�&-�3�D���-�/�$�$�&�)'�V
)���Cr2r�c���|j}|\}}|j|�}|�|j|�n|j||g�|dk(r|j	t|��yy)a�
    Add a header tuple to a request header object.

    @param request: The request to add the header tuple to.
    @type request: L{twisted.web.http.Request}

    @param header: The header tuple to add to the request.
    @type header: A L{tuple} with two elements, the header name and header
        value, both as L{bytes}.

    @return: If the header being added was the C{Content-Length} header.
    @rtype: L{bool}
    scontent-lengthTF)r�rr��
setRawHeadersr��int)rrr��name�valuerms      r0r�r��sm���+�+�N��K�D�%�
�
)�
)�$�
/�F�
���
�
�e���$�$�T�E�7�3�� � ����#�e�*�%��r2)-r�r��collectionsr�typingr�zope.interfacer�	h2.configr�
h2.connection�	h2.errors�	h2.events�
h2.exceptionsr!�"twisted.internet._producer_helpersr�twisted.internet.deferr�twisted.internet.errorr�twisted.internet.interfacesr	r
rrr
�twisted.internet.protocolr�twisted.loggerr�twisted.protocols.policiesr�twisted.python.failurer�twisted.web.errorrr�str�__annotations__�objectr�rr�r�r�r2r0�<module>rDs���

�
���&�������:�+�1���/�!�3�*�5����c����x��
�Y�
�&�N,�8�\�N,�'�N,�b
�Z��M�2�\C�\C�3�\C�~r2
Page Not Found
Parece que el enlace que apuntaba aquí no sirve. ¿Quieres probar con una búsqueda?
¡Hola!